home *** CD-ROM | disk | FTP | other *** search
- //
- //----------------------------------------------------------------------------
- // ObjectComponents
- // (C) Copyright 1994 by Borland International, All Rights Reserved
- //
- // OLE Utility class implementations
- //----------------------------------------------------------------------------
- #include <ocf/ocfpch.h>
- #include <ocf/ocdefs.h>
- #include <osl/ustring.h>
-
- DIAG_DEFINE_GROUP(OcRefCount, true, 1);
-
- #if defined(BI_PLAT_WIN16)
- const char OleErrorStringsDLL[] = "OLE_ERR.DLL";
- #else
- const char OleErrorStringsDLL[] = "OLE_ERRF.DLL";
- #endif
-
-
- TXOle::~TXOle()
- {
- }
-
- TXOle* TXOle::Clone()
- {
- return new TXOle(*this);
- }
-
- void TXOle::Throw()
- {
- THROW( *this );
- }
-
- void TXOle::Check(HRESULT hr, const char far* msg)
- {
- if (FAILED(hr))
- Throw(hr, msg);
- }
-
- void TXOle::Check(HRESULT hr)
- {
- Check(hr, 0);
- }
-
- void TXOle::Throw(HRESULT hr, const char far* msg)
- {
- if (!InstanceCount) {
- char buf[128+1];
- wsprintf(buf, "%s failed, ", msg ? msg : "OLE call");
-
- int len = strlen(buf);
- OleErrorFromCode(hr, buf + len, sizeof buf - len - 2);
- strcat(buf, ".");
-
- WARN(hr != HR_NOERROR, buf);
- throw TXOle(buf, hr);
- }
- }
-
- //
- // If OLE-Error-String DLL exists, & msg string is there, then use
- // it. Otherwise just use the number.
- //
- void TXOle::OleErrorFromCode(HRESULT stat, char far* buffer, int size)
- {
- const char HResultToStringIDFunc[] = "StringIDFromHResult";
- typedef int _export CALLBACK (*TStringIDFromHResult)(HRESULT hr);
-
- int len = 0;
- OFSTRUCT ofs;
- if (OpenFile(OleErrorStringsDLL, &ofs, OF_EXIST) != HFILE_ERROR) {
- HINSTANCE hInst = LoadLibrary(OleErrorStringsDLL);
- if (hInst > (HINSTANCE)HINSTANCE_ERROR) {
- TStringIDFromHResult func =
- (TStringIDFromHResult)GetProcAddress(hInst, HResultToStringIDFunc);
- if (func) {
- int id = func(stat);
- if (id)
- len = ::LoadString(hInst, id, buffer, size);
- }
- FreeLibrary(hInst);
- }
- }
- if (!len) {
- char numBuf[25];
- wsprintf(numBuf, "ErrorCode: %8lX", stat);
- strncat(buffer, numBuf, size - strlen(buffer) - 1);
- }
- buffer[size-1] = 0;
- }
-
- //----------------------------------------------------------------------------
-
- void far*
- TOleAllocator::Alloc(unsigned long size)
- {
- void far* blk = Mem->Alloc(size);
- OLECALL(blk ? 0 : HR_OUTOFMEMORY, "IMalloc::Alloc");
- return blk;
- }
-
- //____________________________________________________________________________
- //
- // TClassId - GUID/IID/CLSID management implementation
- //____________________________________________________________________________
-
- TClassId::TClassId(const char far* idtxt) : Text(0)
- {
- PRECONDITION(idtxt);
-
- OLECALL(::CLSIDFromString(OleStr((char far*)idtxt), &Guid), "Invalid GUID string");
- }
-
- TClassId::TClassId(const GUID far& guid, int offset) : Text(0), Guid(guid)
- {
- Guid.Data1 += (long)offset;
- }
-
- TClassId::TClassId(TGenerate) : Text(0)
- {
- OLECALL(::CoCreateGuid(&Guid), "CoCreateGuid");
- }
-
- TClassId::~TClassId()
- {
- delete const_cast<char*>(Text);
- }
-
- TClassId::operator const char*()
- {
- if (!Text) {
- Text = new char[38+1];
- wsprintf(const_cast<char*>(Text),
- "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
- Guid.Data1, Guid.Data2, Guid.Data3,
- Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3],
- Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
- }
- return Text;
- }
-
- TBaseClassId::TBaseClassId(const GUID far& guid, int maxAlloc)
- : TClassId(guid), MaxAlloc(maxAlloc), Offset(0) {}
-
- TBaseClassId::TBaseClassId(const char far* idtxt, int maxAlloc)
- : TClassId(idtxt), MaxAlloc(maxAlloc), Offset(0) {}
-
- TBaseClassId::TBaseClassId(TGenerate e, int maxAlloc)
- : TClassId(e), MaxAlloc(maxAlloc), Offset(0) {}
-
- TBaseClassId::TBaseClassId(TRegList& regInfo, int maxAlloc)
- : TClassId(), MaxAlloc(maxAlloc), Offset(0)
- {
- const char* str = regInfo["clsid"];
- // must check for valid clasid, else generate??
- if (!str)
- OLECALL(HR_CLASS_CLASSNOTAVAILABLE, "Missing REGDATA clsid");
- OLECALL(::CLSIDFromString(OleStr((char far*)str), &Guid), "Invalid GUID string");
- }
-
- TClassId TBaseClassId::operator [](int offset)
- {
- if(offset > Offset)
- OLECALL(HR_CLASS_CLASSNOTAVAILABLE, "Unassigned GUID");
- return TClassId(Guid, offset);
- }
-
- int TBaseClassId::AllocId()
- {
- ++Offset;
- if(Offset >= MaxAlloc)
- OLECALL(HR_CLASS_CLASSNOTAVAILABLE, "GUID allocation exhausted");
- return Offset;
- }
-
- int TBaseClassId::GetOffset(const GUID far& guid)
- {
- unsigned long offset = guid.Data1 - Guid.Data1;
- if ( offset >= (unsigned long)Offset &&
- ((long far*)&guid)[1] == ((long*)&Guid)[1] &&
- ((long far*)&guid)[2] == ((long*)&Guid)[2] &&
- ((long far*)&guid)[3] == ((long*)&Guid)[3] )
- return int(offset);
- else
- return -1;
- }
-
- //____________________________________________________________________________
- //
- // GUID compare routines use by implementations of IUnknown::QueryInterface
- // the low-order long word is verifed before calling these routines
- // success is indicated by virtue of assigment of the returned interface
- //____________________________________________________________________________
-
- void CmpGuid12(IUnknown* obj, REFIID req, REFIID ref, void far*far* pif)
- {
- if ( ((long far*)&req)[1] == ((long far*)&ref)[1] &&
- ((long far*)&req)[2] == ((long far*)&ref)[2] &&
- ((long far*)&req)[3] == ((long far*)&ref)[3] ) {
- *pif = obj;
- obj->AddRef();
- }
- }
-
- void CmpGuidOle(IUnknown* obj, REFIID req, void far*far* pif)
- {
- if ( ((long far*)&req)[1] == 0x00000000L &&
- ((long far*)&req)[2] == 0x000000C0L &&
- ((long far*)&req)[3] == 0x46000000L ) {
- *pif = obj;
- obj->AddRef();
- }
- }
-
- //____________________________________________________________________________
- //
- // TUnknown - standard implementation of IUnknown
- //____________________________________________________________________________
-
- //
- // Handy container to help watch COM object lifetime when debugging
- //
- #if (__DEBUG >= 2)
- # include <classlib/bags.h>
- typedef TBagAsVector<TUnknown*> TUnknownBag;
- TUnknownBag* UnknownBag;
- #endif
-
- TUnknown::TUnknown() : Outer(&I)
- {
- #if (__DEBUG >= 2)
- if (!UnknownBag)
- UnknownBag = new TUnknownBag(100);
- UnknownBag->Add(this);
- #endif
- }
-
- IUnknown& TUnknown::Aggregate(TUnknown& inner)
- {
- if (I.Inner)
- return I.Inner->Aggregate(inner);
- ((IUnknown&)inner).AddRef();
- I.Inner = &inner;
- return *Outer;
- }
-
- TUnknown::~TUnknown()
- {
- #if (__DEBUG >= 2)
- UnknownBag->Detach(this);
- #endif
- TRACEX(OcRefCount, 1,
- "~TUnknown() @" << (void*)this << ", RefCnt:" << I.RefCnt);
- WARNX(OcRefCount, I.RefCnt != 0, 0,
- "~TUnknown() @ " << (void*)this << ", RefCnt:" << I.RefCnt);
-
- // deleted by TUnknownI member
- }
-
- //
- // QueryObject used when TUnknown is in constructor/destructor
- //
- HRESULT
- TUnknown::QueryObject(const GUID far& /*iid*/, void far* far* /*pif*/)
- {
- return ResultFromScode(E_NOINTERFACE);
- }
-
- HRESULT _IFUNC
- TUnknown::TUnknownI::QueryInterface(const GUID far& iid, void far* far* pif)
- {
- *pif = 0;
- if (iid.Data1 == 0) { // IID_IUnknown.Data1
- CmpGuidOle(this, iid, pif);
- if (*pif)
- return NOERROR;
- }
- if (Host().QueryObject(iid, pif) == NOERROR)
- return NOERROR;
- if (Inner)
- return Inner->ThisUnknown().QueryInterface(iid, pif);
- else
- return ResultFromScode(E_NOINTERFACE);
- }
-
- unsigned long _IFUNC
- TUnknown::TUnknownI::AddRef()
- {
- TRACEX(OcRefCount, 2,
- "AddRef on " << (void*)&Host() << " to " << (RefCnt+1));
- return ++RefCnt;
- }
-
- unsigned long _IFUNC
- TUnknown::TUnknownI::Release()
- {
- TRACEX(OcRefCount, 2,
- "Release on " << (void*)&Host() << " to " << (RefCnt-1));
- if (--RefCnt != 0)
- return RefCnt;
- if (Inner) {
- Inner->ThisUnknown().Release();
- Inner = 0;
- }
- delete &Host();
- return 0;
- }
-
- unsigned long
- TUnknown::GetRefCount()
- {
- if (Outer == &I)
- return I.RefCnt;
- Outer->AddRef();
- return Outer->Release();
- }
-
- TUnknown::TUnknownI::~TUnknownI()
- {
- if (RefCnt) // in case destructor called before RefCnt goes to 0
- ::CoDisconnectObject(this,0);// OLE will try to remove external references
- }
-
- //____________________________________________________________________________
- //
- // TLocaleString wrapper method replacements using OLE2 NLS functions for Win16
- //____________________________________________________________________________
-
- #if defined(BI_PLAT_WIN16)
-
- TLangId
- TLocaleString::GetSystemLangId()
- {
- return ::GetSystemDefaultLangID();
- }
-
- TLangId
- TLocaleString::GetUserLangId()
- {
- return ::GetUserDefaultLangID();
- }
-
- int
- TLocaleString::CompareLang(const char far* s1, const char far* s2, TLangId lang)
- {
- return ::CompareStringA(lang, NORM_IGNORECASE | NORM_IGNORENONSPACE,
- s1,-1, s2,-1) - 2;
- }
-
- #endif
-
-